#include "config.h"

#include <libusb.h>

#include "mp710.h"
#include "mpcommon.h"

enum libusb_error exchange_feature_reports_switch_port_state(libusb_device_handle *devh, unsigned int relay, bool state) {
    int transferred = 0;
    unsigned char in[8];
    unsigned char out[8];
    int i = 0;
    enum libusb_error result = LIBUSB_SUCCESS;

    for (i=0; i < 8; i++) {
	out[i]=0x00;
	in[i]=0x00;
    }

    out[0] = 0x63;
    out[1] = relay;				//RELAY PORT N
    out[2] = state ? 0x80 : 0x00;		//0x80 - ON, 0x00 - OFF
    out[3] = 0x00;
    out[4] = 0x00;
    out[5] = 0x00;
    out[6] = 0x00;
    out[7] = 0x00;

    if (result = send_feature_report(devh, out, sizeof(out), &transferred) == LIBUSB_SUCCESS && transferred > 0) {
	if (result = receive_feature_report(devh, in, sizeof(in), &transferred) == LIBUSB_SUCCESS && transferred > 0) {

	}
    }

    return result;
}

enum libusb_error exchange_feature_reports_get_port_state(libusb_device_handle *devh, unsigned int relay, bool *state) {
    int transferred = 0;
    unsigned char in[8];
    unsigned char out[8];
    int i = 0;
    enum libusb_error result = LIBUSB_SUCCESS;

    for (i=0; i < 8; i++) {
	out[i]=0x00;
	in[i]=0x00;
    }

    out[0] = 0x36;
    out[1] = relay;
    out[2] = 0x00;
    out[3] = 0x00;
    out[4] = 0x00;
    out[5] = 0x00;
    out[6] = 0x00;
    out[7] = 0x00;

    if (result = send_feature_report(devh, out, sizeof(out), &transferred) == LIBUSB_SUCCESS && transferred > 0) {
	if (result = receive_feature_report(devh, in, sizeof(in), &transferred) == LIBUSB_SUCCESS && transferred > 0) {
	    if (in[0] == 0x36 && in[1] == relay) {
		if ((in[2] & 0x80) == 0x80) {
		    *state = true;
		} else {
		    *state = false;
		}
	    } else {
		return LIBUSB_ERROR_OTHER;
	    }
	}
    }

    return result;
}

void print_devices_list() {
    struct		libusb_device_handle		*devh = NULL;
    libusb_device					**devices = NULL;
    libusb_context 					*ctx = NULL;
    enum		libusb_error			result;

    result = libusb_init(&ctx);
    libusb_set_debug(ctx, 0x03);

    if (result == LIBUSB_SUCCESS) {
	int count = libusb_get_device_list(ctx, &devices);
	
	if (count > 0) {
	    for (count--; count >= 0; count--) {
		struct libusb_device_descriptor *desc = calloc(1, sizeof(struct libusb_device_descriptor));
		unsigned int id = 0;
		unsigned char family = 0;
		result = libusb_get_device_descriptor(devices[count], desc);
		if (result ==  LIBUSB_SUCCESS) {
		    if (desc->idVendor == VENDOR_ID && desc->idProduct == PRODUCT_ID) {
			result = libusb_open(devices[count], &devh);
			if (result == LIBUSB_SUCCESS) {
			    result = exchange_feature_reports_dev_id(devh, &id, &family);
			    if (result == LIBUSB_SUCCESS || result > 0) {
				fprintf(stdout, "Bus:0x%02X Device:0x%02X VID:0x%04X PID:0x%04X MP-FAMILY:0x%02X MP-ID:0x%08X\n", libusb_get_bus_number(devices[count]), libusb_get_device_address(devices[count]), desc->idVendor, desc->idProduct, family, id);
			    } else {
				fprintf(stderr, "Error communicating with the device, device will be reseted\n");
				libusb_reset_device(devh);
			    }
			    libusb_close(devh);
			} else {
			    fprintf(stderr, "Unable to open device\n");
			}
		    }
		} else {
		    fprintf(stderr, "Unable to get device descriptor\n");
		}
		free(desc);
	    }
	}
	libusb_free_device_list(devices, true);

	libusb_exit(ctx);
    } else {
	fprintf(stderr, "libusb_init failed\n");
    }
}

int main (int argc, char *argv[]) {
    const unsigned char *method = getenv("REQUEST_METHOD");

    fprintf(stdout, "Content-Type: text/plain;charset=us-ascii\n\n");

    if (method != NULL) {
	if (strcmp(method, "GET") == 0) {
	    const unsigned char *query = getenv("QUERY_STRING");
	    if (query != NULL) {
		unsigned char *query_string = strdup(query);					// зачищать память query_string
		unsigned char *param = strtok(query_string, "&");
		unsigned char *query_param;
		unsigned char *port_param;
		unsigned char *state_param;
		unsigned char *devid_param;
		do {
		    unsigned char *value = strchr(param, '=');
		    if (value != NULL) {
			if (strncmp("query", param, value - param) == 0) {
			    query_param = strdup(++value);
			}else if (strncmp("port", param, value - param) == 0) {
			    port_param = strdup(++value);
			}else if (strncmp("devid", param, value - param) == 0) {
			    devid_param = strdup(++value);
			}else if (strncmp("state", param, value - param) == 0) {
			    state_param = strdup(++value);
			}
		    }
		    param = strtok(NULL, "&");
		} while (param != NULL);

		if (strcmp("state", query_param) == 0) {
		    fprintf(stdout, "STATE\n");
		} else if (strcmp("switch", query_param) == 0) {
		    fprintf(stdout, "SWITCH\n");
		} else if (strcmp("list", query_param) == 0) {
		    fprintf(stdout, "LIST\n");
		}
	    } else {
		fprintf(stdout, "Empty query\n");
	    }
//POST
	} else if (strcmp(method, "POST") == 0) {
	    fprintf(stdout, "POST method\n");
	} else {
	    fprintf(stdout, "Method: %s\n", method);
	}
    } else {
	
    }

    return 0;
}
